import {VNode} from './vnode';
import {VText} from './vtext';
import {applyStyle} from './style';

export function createElement(vnode:any,opts?:any) {
     let doc = opts ? opts.document || document : document;
    // let doc=document;
    let warn=opts?opts.warn:null;
    if (vnode.type==='VirtualText') {
        return doc.createTextNode((vnode as VText).text)
    }
     let vnodet=vnode as VNode;
     let node:HTMLElement;
     if (vnodet.namespace) {
         doc.createElementNS(vnodet.namespace,vnodet.tagName);
     }else{
        node=doc.createElement(vnodet.tagName);
     }    
    let props=vnodet.properties;
    applyProperties(node, props);
    let children = vnode.children

    for (var i = 0; i < children.length; i++) {
        var childNode = createElement(children[i], opts)
        if (childNode) {
            node.appendChild(childNode)
        }
    }
    return node;

}

function isObject(s){
    return  Object.prototype.toString.call(s)==='[object Object]';
}

function applyProperties(node, props, previous?) {
    for (var propName in props) {
        var propValue = props[propName]

            if (isObject(propValue)) {
                patchObject(node, props, previous, propName, propValue);
            } else {
                node[propName] = propValue;
            }
     
    }
}
function patchObject(node, props, previous, propName, propValue) {
    var previousValue = previous ? previous[propName] : undefined

    // Set attributes
    if (propName === "attributes") {
        for (var attrName in propValue) {
            var attrValue = propValue[attrName]
            if (attrValue === undefined) {
                node.removeAttribute(attrName)
            } else {
                // node.setAttribute(attrName, attrValue)
                node[attrName]=attrValue;
            }
        }

        return
    }

    if(previousValue && isObject(previousValue) &&
        getPrototype(previousValue) !== getPrototype(propValue)) {
        node[propName] = propValue
        return
    }

    if (!isObject(node[propName])) {
        node[propName] = {}
    }
    if (propName === "style") {
        applyStyle(node,propValue);
    }
    // var replacer = propName === "style" ? "" : undefined
    // for (var k in propValue) {
    //     console.log(node[propName]);
    //     var value = propValue[k]
    //     node[propName][k] = value;
    // }
}

function getPrototype(value) {
    if (Object.getPrototypeOf) {
        return Object.getPrototypeOf(value)
    } else if (value.__proto__) {
        return value.__proto__
    } else if (value.constructor) {
        return value.constructor.prototype
    }
}